package bookworm;

import java.util.LinkedList;

import retrievedatafromrevishapi.AccessBooksData;

/**
 * this class is responsible for looking for how many days take to read a certain book
 * specified by the user. It gets the reading history of top reviewers and searches
 * for the book specified by the user
 *
 */
public class LooksForHowManyDaysToReadBook 
{
	/**
	 * topReviewersNames contains the user names which we'll access
	 * reading history looking for the specified book. the top
	 * reviewers, apparently, have the biggest reading history because of our rating
		system for reviewer's rating where we use the reading history. For Details of
		calculus, see class CalculatesRatingsBookworm from package bookworm.
	 */
	private LinkedList<String> topReviewersNames;
	
	/**
	 * list responsible for storing all reading history data of or system. Each
	 * book history data contains a history of read books' started date and
	 * finished date, so we'll use it to determine how many days were taken
	 * to finish a book.
	 */
	private LinkedList<BookHistoryData> allBooksHistoryData;
	
	public LooksForHowManyDaysToReadBook()
	{
		topReviewersNames = new LinkedList<String>();
		/*these top reviewers are based on our rating system which is explained
		 * in class CalculatesRatingsBookworm from same package bookworm
		 */
		this.topReviewersNames.add("A. Bowdoin Van Riper");
		this.topReviewersNames.add("Elizabeth");
		this.topReviewersNames.add("jaemi");
		this.topReviewersNames.add("3rs");
		this.topReviewersNames.add("Tara");
		this.topReviewersNames.add("deargreenplace");
		this.topReviewersNames.add("Sundance");
		this.topReviewersNames.add("JustPeachy");
		this.topReviewersNames.add("max");
		
		allBooksHistoryData = new LinkedList<BookHistoryData>();
		
		
	}
	
	/**
	 * the user will type the book name in which he/she would like to know how long does
	 * it take to finish it and our system will look for books that match with
	 * this name in all reading history that's stored in our system.   
	 * @param bookName book name 
	 * @return book names in books history matching the bookName
	 */
	public LinkedList<String> searchForBooksInHistoryWithThisName(String bookName)
	{
		LinkedList<String> bookTitlesInHistoryMatchingBookName =
				new LinkedList<String>();
		for(int i = 0; i < this.allBooksHistoryData.size(); i++)
		{
			BookHistoryData bookReadingHistory = this.allBooksHistoryData.get(i);
			String bookNameOfreadingHistory = bookReadingHistory.getBookTitle();
			
			
			String bookNameLowerCase = bookName.toLowerCase();
			String bookNameOfReadingHistoryLowercase =
					bookNameOfreadingHistory.toLowerCase();
			if(bookNameOfReadingHistoryLowercase.contains(bookNameLowerCase) == true)
			{
				/*
				 * found a book title containing this bookName, but is this book title
				 * already in the list bookTitlesInHistoryMatchingBookName? if yes, then we must not add it
				 */
				if(bookTitlesInHistoryMatchingBookName.contains(bookNameOfreadingHistory) == false)
				{
					bookTitlesInHistoryMatchingBookName.add(bookNameOfreadingHistory);
				}
			}
		}
		
		return bookTitlesInHistoryMatchingBookName;
	}
	
	/**
	 * Based on an average of reading history from top reviewers, it tells how many days it takes to finish a certain book
	 * @param bookName book title in which the user wants to know how long does it take to finish it.
	 * @return returns an object with details of the search result(E.G.:book cover address and how many days to finish it). Notice that 
	 * NOT FINDING THE BOOK IN ANY READING HISTORY will lead the book cover address to "book cover not found" and the days equal to -1(as specified in object constructor).
	 */
	public BookCoverAndHowManyDaysToFinishIt howManydaysToFinishThisBook(String bookName)
	{
		BookCoverAndHowManyDaysToFinishIt result = new BookCoverAndHowManyDaysToFinishIt(bookName);
		/*
		 * we'll calculate an average of reading time based on book history data
		 * that matches with this book name.
		 */
		int bookHistoryDataMatchingThisBook = 0;
		long sumOfAllBookReadingTime = 0;
		for(int i = 0; i < this.allBooksHistoryData.size(); i++)
		{
			BookHistoryData bookReadingHistory = this.allBooksHistoryData.get(i);
			String bookNameOfreadingHistory = bookReadingHistory.getBookTitle();
			if(bookName.compareToIgnoreCase(bookNameOfreadingHistory) == 0)
			{
				/*
				 * found a reading history for this book, then let's set book medium cover
				 * for our result(BookCoverndHowManyDaysToFinishIt).
				 */
				String bookCoverOfreadingHistory = bookReadingHistory.getMediumCover();
				if(bookCoverOfreadingHistory.length() > 0)
				{
					result.setBookCoverAddress(bookCoverOfreadingHistory);
				}
				
				bookHistoryDataMatchingThisBook = bookHistoryDataMatchingThisBook + 1;
				long howLongToFinishBookInAHistory = 
						bookReadingHistory.calculateDaysToFinishABook();
				sumOfAllBookReadingTime = sumOfAllBookReadingTime + howLongToFinishBookInAHistory;
			}
		}
		
		if(bookHistoryDataMatchingThisBook != 0)
		{
			long howManydaysToFinishBook = (sumOfAllBookReadingTime / bookHistoryDataMatchingThisBook);
			result.setHowManyDaysToFinishBook(howManydaysToFinishBook);
		}
		
		return result;
	}
	
	
	/**
	 * this method will populate allBooksHistoryData. It will request reading history
	 * from the top reviewers and then get their book history.
	 */
	public void lookForAllBooksHistoryData()
	{
		//have we already stored all book history data?
		if(this.allBooksHistoryData.size() == 0)
		{
			//nu-huh, not that I know!then, let's look for all book history data!
			for(int i = 0; i < topReviewersNames.size(); i++)
			{
				String topreviewerUserName = this.topReviewersNames.get(i);
				AccessBooksData accessBookData = AccessBooksData.getAccessBooksData();
				LinkedList<BookHistoryData> readingHistoryOfUser = 
						accessBookData.getReadingHistoryOfAUser(topreviewerUserName);
				this.allBooksHistoryData.addAll(readingHistoryOfUser);
			}
		}
		
	}
	
	
	
	

}
